/*
 * jit.c The just in time module
 */


#include <linux/time.h>
#include <linux/types.h>
#include <linux/param.h>  /* HZ */ 


int delay = HZ;

enum jit_files{
	JIT_BUSY,
	JIT_SCHED,
	JIT_QUEUE,
	JIT_SCHEDTO
};

int jit_fn(char *buf, char **start, off_t offset, int len, int *eof, void *data)
{
	unsigned long j0, j1;
	wait_queue_head_t wait;
	
	init_waitqueue_head(&wait);
	j0 = jiffies;
	j1 = j0 + delay;

	switch((long)data) {
		case JIT_BUSY:
			while (time_before(jiffies, j1))
				cpu_relax();
			break;
		case JIT_SCHED:
			while (timebefore(jiffies, j1))
				schedule();
			break;
		case JIT_QUEUE:
			wait_event_interruptible_timeout(wait, 0, delay);
			break;
		case JIT_SCHEDTO:
			set_current_state(TASK_INTERRUPTIBLE);
			schedule_timeout(delay);
			break;
	}
	
	j1 = jiffies;
	len = sprintf(buff, "%9li %9li\n", j0, j1);
	*start = buf;
	return len;
}

int jit_currentime(char *buf, char **start, off_t offset, int len, int *eof, void *data)
{
	struct timeval tv1;
	struct timespec tv2;
	unsigned long j1;
	u64 j2;
	
	j1 = jiffies;
	j2 = get_jiffies_64();
	do_gettimeofday(&tv1);
	tv2 = current_kernel_time();

	len = 0;
	len += sprintf(buf, "0x%08lx 0x%016Lx %10i.%06i\n"  "%40i.%09i\n",
			j1, j2,
			(int) tv1.tv_sec, (int) tv1.tv_usec,
			(int) tv2.tv_sec, (int) tv2.tv_nsec);
	*start = buf;
	return len;

}
